package com.atguigu.gmall.payment.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.response.AlipayTradeCloseResponse;
import com.atguigu.gmall.constant.MqConst;
import com.atguigu.gmall.model.enums.PaymentStatus;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.payment.PaymentInfo;
import com.atguigu.gmall.payment.mapper.PaymentMapper;
import com.atguigu.gmall.payment.service.PaymentService;
import com.atguigu.gmall.service.RabbitService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;

/**
 * @author mgx
 * @create 2024-09-04 17:34
 * @Description
 */
@Service
@SuppressWarnings("all")
public class PaymentServiceImpl implements PaymentService {

    @Autowired
    private PaymentMapper paymentMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RabbitService rabbitService;


    /**
     * 保存交易记录
     * @param orderInfo
     * @param paymentType 支付类型（1：微信 2：支付宝）
     */
    @Override
    public void savePaymentInfo(OrderInfo orderInfo, String paymentType) {
        // 查询支付记录是否存在
        QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id", orderInfo.getId());
        wrapper.eq("payment_type", paymentType);
        Integer count = paymentMapper.selectCount(wrapper);
        if(count > 0) return;

        // 保存订单记录
        PaymentInfo paymentInfo = new PaymentInfo();
        paymentInfo.setOutTradeNo(orderInfo.getOutTradeNo());
        paymentInfo.setOrderId(orderInfo.getId());
        paymentInfo.setUserId(orderInfo.getUserId());
        paymentInfo.setPaymentType(paymentType);
        paymentInfo.setTotalAmount(orderInfo.getTotalAmount());
        paymentInfo.setSubject(orderInfo.getTradeBody());
        paymentInfo.setPaymentStatus(PaymentStatus.UNPAID.name());

        paymentMapper.insert(paymentInfo);
    }

    /**
     * 根据交易号和支付渠道获得支付记录信息
     * @param outTradeNo 交易号
     * @param paymentType 支付渠道
     * @return
     */
    @Override
    public PaymentInfo getPaymentInfo(String outTradeNo, String paymentType) {
        LambdaQueryWrapper<PaymentInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PaymentInfo::getOutTradeNo, outTradeNo)
                .eq(PaymentInfo::getPaymentType, paymentType);

        return paymentMapper.selectOne(wrapper);
    }

    /**
     * 支付成功-修改支付状态
     * @param outTradeNo 交易号
     * @param paymentType 支付渠道
     * @param paramsMap 支付宝异步回调信息
     */
    @Override
    public void paySuccess(String outTradeNo, String paymentType, Map<String, String> paramsMap) {
        // 获取支付记录
        PaymentInfo paymentInfoQuery = this.getPaymentInfo(outTradeNo, paymentType);
        if(paymentInfoQuery == null) {
            return;
        }
        try {
            PaymentInfo paymentInfo = new PaymentInfo();
            paymentInfo.setTradeNo(paramsMap.get("trade_no"));
            paymentInfo.setCallbackTime(new Date());
            paymentInfo.setPaymentStatus(PaymentStatus.PAID.name());
            paymentInfo.setCallbackContent(JSON.toJSONString(paramsMap));

            LambdaQueryWrapper<PaymentInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(PaymentInfo::getOutTradeNo, outTradeNo)
                    .eq(PaymentInfo::getPaymentType, paymentType);

            paymentMapper.update(paymentInfo, wrapper);
        } catch (Exception e) {
            //  删除key
            redisTemplate.delete(paramsMap.get("notify_id"));
            throw new RuntimeException(e);
        }
        // 发送通知给订单服务，修改订单状态
        rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_PAYMENT_PAY,
                MqConst.ROUTING_PAYMENT_PAY, paymentInfoQuery.getOrderId());
    }

    /**
     * 更新支付记录信息
     * @param outTradeNo 交易号
     * @param paymentInfo 支付信息
     */
    @Override
    public void updatePaymentInfo(String outTradeNo, String paymentType, PaymentInfo paymentInfo) {
        LambdaQueryWrapper<PaymentInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PaymentInfo::getOutTradeNo, outTradeNo)
                .eq(PaymentInfo::getPaymentType, paymentType);

        paymentMapper.update(paymentInfo, wrapper);

    }

    /**
     * 关闭本地交易记录
     * @param orderId 订单id
     */
    @Override
    public void closePayment(Long orderId) {
        LambdaQueryWrapper<PaymentInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PaymentInfo::getOrderId, orderId);
        // 判断是否存在交易记录
        Integer count = paymentMapper.selectCount(wrapper);
        if(count == null || count.intValue() == 0) return;
        // 存在交易记录关闭订单
        PaymentInfo paymentInfo = new PaymentInfo();
        paymentInfo.setPaymentStatus(PaymentStatus.CLOSED.name());
        paymentMapper.update(paymentInfo, wrapper);
    }

}
